Jekyll Secret Posts

Jekyll plugin for unlisted posts served at hashed, share-only URLs

Feb 2026

Jekyll Secret Posts

TL;DR

  • Share-Only URL ๋ฐฉ์‹์œผ๋กœ ๋น„๊ณต๊ฐœ ํฌ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” Jekyll ํ”Œ๋Ÿฌ๊ทธ์ธ์ž…๋‹ˆ๋‹ค.
  • ๋ฏผ๊ฐํ•œ ๋‚ด์šฉ์„ URL์„ ์•„๋Š” ์‚ฌ๋žŒ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋ธ”๋กœ๊ทธ์— ์˜ฌ๋ฆฌ๊ธฐ ์œ„ํ•ด ๊ฐœ๋ฐœํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ํ•ด์‹œ ๊ธฐ๋ฐ˜ permalink, sitemapยท๊ฒ€์ƒ‰์—”์ง„ ์ œ์™ธ, ๊ฐ„๋‹จํ•œ ์—ฐ๋™์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.


๊ธฐํš

๋ฐฐ๊ฒฝ

Resume Image

์ €๋Š” ์š”์ฆ˜ ์ทจ์—…์„ ์œ„ํ•ด ์ด๋ ฅ์„œ๋ฅผ ์“ฐ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ œ ๊ฒฝ๋ ฅ, ์ง„ํ–‰ํ•œ ํ”„๋กœ์ ํŠธ๋“ค์„ ๋น„๋กฏํ•œ ์ง€๊ธˆ๊นŒ์ง€์˜ ๊ฒฝํ—˜์„ ๋‹ด์•„๋‚ด๊ณ  ์žˆ๋Š”๋ฐ, ์–ด๋–ป๊ฒŒ ๋ชจ๋“  ๋‚ด์šฉ์„ ์ด๋ ฅ์„œ ์•ˆ์— ๋‹ด์•„๋‚ผ ์ˆ˜ ์žˆ์„์ง€ ๊ณ ๋ฏผํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ ฅ์„œ ์•ˆ์— ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๋ชจ๋“  ์„ค๋ช…์„ ๋„ฃ์„ ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋žฌ๋‹ค๊ฐ€๋Š” ์ด๋ ฅ์„œ๊ฐ€ 10ํŽ˜์ด์ง€๋„ ๋„˜์–ด๋ฒ„๋ฆด ํ…Œ๋‹ˆ๊นŒ์š”. ๊ทธ๋ ‡๋‹ค๊ณ  ์„ค๋ช…์„ ๋บ€๋‹ค๋ฉด, ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ •์„ ์ œ๋Œ€๋กœ ๋‹ด์•„๋‚ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ €๋Š” ์ƒ์„ธํ•œ ๋‚ด์šฉ์„ ๋‹ด์€ ๋ณ„๋„์˜ ์™ธ๋ถ€ ๋ฌธ์„œ๋ฅผ ๋งŒ๋“ค์–ด, ์ด๋ ฅ์„œ์—์„œ๋Š” ๊ฐ„๋‹จํ•œ ์„ค๋ช…๋งŒ ์ œ๊ณตํ•˜๊ณ  ๋””ํ…Œ์ผํ•œ ๊ฒฝํ—˜์€ ์™ธ๋ถ€ ๋ฌธ์„œ์—์„œ ํ’€์–ด๋‚ด๋Š” ๋ฐฉ๋ฒ•์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์™ธ๋ถ€ ๋ฌธ์„œ๋Š” ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์–ด์•ผ ํ• ๊นŒ์š”? ํŒŒ์ผ์„ ๋˜ ๋งŒ๋“ค์ž๋‹ˆ ์ด๋ ฅ์„œ์— ๋‹ด๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฅผ ๋ฐ” ์—†์—ˆ๊ณ , Notion์ด๋‚˜ Google Docs๋ฅผ ์“ฐ์ž๋‹ˆ ๋””์ž์ธ์ด ๋งˆ์Œ์— ๋“ค์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

Blog Projects Page

๊ทธ๋•Œ, ์ œ ๋ธ”๋กœ๊ทธ๊ฐ€ ๋ˆˆ์— ๋“ค์–ด์™”์Šต๋‹ˆ๋‹ค. ๋””์ž์ธ๋„ ๊ดœ์ฐฎ๊ณ , UI๋ฅผ ๋งˆ์Œ๋Œ€๋กœ ์ปค์Šคํ…€ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, URL๋งŒ ๊ณต์œ ํ•˜๋ฉด ๋ฐ”๋กœ ์ ‘์†ํ•  ์ˆ˜ ์žˆ๊ธฐ์— ์ตœ๊ณ ์˜ ๋Œ€์•ˆ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ํšŒ์‚ฌ์˜ ์†Œํ”„ํŠธ์›จ์–ด ์•„ํ‚คํ…์ฒ˜์™€ ๋„๋ฉ”์ธ์  ๋งฅ๋ฝ์ด ๋‹ด๊ธด ๊ฒฝ๋ ฅ์—์„œ์˜ ๊ฒฝํ—˜๋“ค์„ ๋ธ”๋กœ๊ทธ์— ๊ณต๊ฐœ์ ์œผ๋กœ ์“ฐ๋Š” ๊ฒƒ์€ ๋ฌธ์ œ์˜ ์†Œ์ง€๊ฐ€ ์žˆ์—ˆ๊ธฐ์—, ๋ธ”๋กœ๊ทธ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜๋Š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋‹จ์ˆœํžˆ ํŠน์ • ๊ธ€์„ ๋ชฉ๋ก์— ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์—ˆ์œผ๋‚˜, ๋ฏผ๊ฐํ•œ ์ฃผ์ œ์ธ ๋งŒํผ ๋” ํ™•์‹คํ•˜๊ณ  ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

Google Drive Link Popup

drive.google.com/drive/folders/1FsvTO123Bb3mSQu456HwSAdpD00mo6tM?usp=sharing

๋ฐฉ๋ฒ•์„ ๊ณ ๋ฏผํ•˜๋˜ ์ค‘, Google Drive์˜ ๊ณต์œ  URL ๊ธฐ๋Šฅ์ด ๋ˆˆ์— ๋“ค์–ด์™”์Šต๋‹ˆ๋‹ค. URL์„ ์•„๋Š” ์‚ฌ๋žŒ์€ ๋ˆ„๊ตฌ๋‚˜ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ชจ๋ฅด๋Š” ์‚ฌ๋žŒ์ด ์ •ํ™•ํžˆ ์ฐพ๋Š” ๊ฒƒ์€ ์ˆ˜ํ•™์ ์œผ๋กœ ๋ถˆ๊ฐ€๋Šฅ์— ๊ฐ€๊นŒ์šด Share-Only URL.

์ด๋Š” ์ œ ์š”๊ตฌ ์‚ฌํ•ญ์— ์ •ํ™•ํžˆ ๋“ค์–ด๋งž์•˜๊ณ , Share-Only URL ์ƒ์„ฑ์„ ์ž๋™ํ™”ํ•˜๋Š” Jekyll ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋งŒ๋“ค๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.


๋ชฉํ‘œ

1. Share-Only URL

์ˆจ๊ฒจ์ง„ ์•„ํ‹ฐํด์€ ๋ฐ˜๋“œ์‹œ URL์„ ์•„๋Š” ์‚ฌ๋žŒ๋งŒ์ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ ์ˆจ๊ฒจ์ง„ ์•„ํ‹ฐํด์€ ์•„ํ‹ฐํด ๋ชฉ๋ก์— ๋…ธ์ถœํ•˜์ง€ ์•Š๋Š” ๊ฒƒ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Sitemap์—๋„ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•„์•ผ ํ•˜๊ณ , ๊ฒ€์ƒ‰ ์—”์ง„์˜ ์ธ๋ฑ์‹ฑ๋„ ํ”ผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, ์•„๋ฌด๋ฆฌ ์ž˜ ์ˆจ๊ธฐ๋”๋ผ๋„ ์œ ์ถ”๋‚˜ ๋ฌด์ž‘์œ„ ๋Œ€์ž…์œผ๋กœ URL์„ ์•Œ์•„๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋ฌด์šฉ์ง€๋ฌผ์ด๊ธฐ์— Google Drive์˜ ์˜ˆ์ฒ˜๋Ÿผ ์œ ์ถ”๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•œ ๋‚œ์ˆ˜ ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


2. ๋งค๋„๋Ÿฌ์šด ์—ฐ๋™

๋‹ค๋ฅธ Jekyll ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์˜ ํ™˜๊ฒฝ ์„ค์ •์— ๊ณ ์ƒํ•œ ๊ฒฝํ—˜์ด ์žˆ๊ธฐ์—, ์ง์ ‘ ๊ฐœ๋ฐœํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์—์„œ๋Š” ๋งค๋„๋Ÿฌ์šด ๊ฐœ๋ฐœ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ README๋งŒ ์ฝ์œผ๋ฉด 1๋ถ„๋งŒ์— ์—ฐ๋™์ด ๋๋‚˜๊ณ , ์ปค์Šคํ…€ ์„ค์ •์€ ์ตœ์†Œํ•œ์˜ ํ•„์š” ๊ธฐ๋Šฅ๋“ค๋งŒ์„ ์ตœ์†Œํ•œ์˜ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ œ๊ณตํ•˜๋„๋ก ๊ตฌ์„ฑํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ, ์ œ ๋ธ”๋กœ๊ทธ๋ฅผ ๋น„๋กฏํ•œ ๋งŽ์€ Jekyll ์›น์‚ฌ์ดํŠธ๋“ค์€ ๋Œ€๋ถ€๋ถ„ ์—ฌ๋Ÿฌ ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ์ถ•๋˜๊ธฐ์—, ๋ณต์žกํ•œ ์„ค์ • ์—†๋Š” ๋งค๋„๋Ÿฌ์šด ์—ฐ๋™์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค๋ฅธ ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ์˜ ํ˜ธํ™˜์„ฑ์„ ํ™•๋ณดํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.


๊ฐœ๋ฐœ

๊ธฐ์ˆ  ์Šคํƒ

Ruby 2.7 ์ด์ƒ, Jekyll 4.x ํ™˜๊ฒฝ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐœ๋ฐœํ•˜์˜€์Šต๋‹ˆ๋‹ค.

Jekyll ์›น์‚ฌ์ดํŠธ์™€ ํ†ตํ•ฉํ•ด์•ผ ํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์ธ ์ ์„ ๊ณ ๋ คํ•˜์—ฌ Jekyll ์™ธ์˜ ์ถ”๊ฐ€ ์˜์กด์„ฑ์„ ๋ฐฐ์ œํ•˜๊ณ  Ruby ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋งŒ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋ฆฐํ„ฐ๋Š” Ruby ์ƒํƒœ๊ณ„์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” RSpec๊ณผ RuboCop์„ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.


์•„ํ‚คํ…์ฒ˜

flowchart LR subgraph INPUT["Input"] config["_config.yml"] env["ENV"] md["_secret/"] end Config["Config"] UrlTokenizer["UrlTokenizer"] Hooks["Hooks"] Generator["Generator"] subgraph OUTPUT["Output"] secret["Secret posts"] redirect["Redirect"] end config --> Config env --> Config md -->|"documents"| Hooks Config -->|"settings (salt, token_length)"| UrlTokenizer Config -->|"settings"| Hooks Config -->|"settings"| Generator UrlTokenizer -->|"token"| Hooks UrlTokenizer -->|"token"| Generator Hooks -->|"permalink, noindex"| secret Generator -->|"redirect page"| redirect

๋ณธ ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ํฌ๊ฒŒ Config, UrlTokenizer, Hooks, Generator ๋„ค ๋ชจ๋“ˆ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.


Config

flowchart LR subgraph INPUT["Input"] yaml["_config.yml\nsecret_posts"] baseurl["baseurl"] env["JEKYLL_SECRET_SALT"] end subgraph CONFIG["Config"] read["Read & validate"] fallback["Default fallback"] normalize["Normalize"] end subgraph OUTPUT["Output"] s_dir["source_dir"] coll["collection_name"] prefix["url_prefix"] salt["salt"] layout["secret_index_layout"] redirect["redirect_url"] len["token_length"] list["list_urls"] end yaml --> read baseurl --> read env --> read read --> fallback fallback --> normalize normalize --> s_dir normalize --> coll normalize --> prefix read --> salt normalize --> layout normalize --> redirect normalize --> list

Config๋Š” Jekyll site ์„ค์ •๊ณผ _config.yml์˜ ์ปค์Šคํ…€ ์„ค์ •, Salt ํ™˜๊ฒฝ ๋ณ€์ˆ˜(JEKYLL_SECRET_SALT)๋ฅผ ์ฝ์–ด ๋นŒ๋“œ Lifecycle ์ „์ฒด์—์„œ ์ฐธ์กฐ๋  ์ „์—ญ ์„ค์ •๊ฐ’์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ปค์Šคํ…€ ์„ค์ •์€ ์ „๋ถ€ Optional๋กœ, ๋น„๋ฐ€ Collection์˜ ๊ฒฝ๋กœ์™€ ์‹๋ณ„์ž, ๋น„๋ฐ€ ๋ฌธ์„œ๊ฐ€ ์œ„์น˜ํ•  URL prefix ๋“ฑ Jekyll์˜ ๊ธฐ๋ณธ ์„ค์ •๊ณผ ํ˜ธํ™˜๋˜๋Š” ์ตœ์†Œํ•œ์˜ ์„ค์ •๋งŒ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์„ค๋ช…์€ README.md๋ฅผ ์ฐธ์กฐํ•ด์ฃผ์„ธ์š”.


UrlTokenizer

flowchart LR subgraph IN["Input"] c["Config"] lbl["collection_label"] pth["relative_path"] end subgraph TOK["UrlTokenizer"] t["token_for"] end OUT["token"] c --> t lbl --> t pth --> t t -->|"salt + label + path โ†’ SHA256 โ†’ trim"| OUT

UrlTokenizer๋Š” ๋น„๋ฐ€ ์ปฌ๋ ‰์…˜ ์‹๋ณ„์ž(collection_name)์™€ ์ƒ๋Œ€ ๊ฒฝ๋กœ(source_dir)๋ฅผ ํ•ด์‹œํ•˜์—ฌ URL๋กœ ์‚ฌ์šฉ๋  ๊ณ ์ • ๊ธธ์ด์˜ hex ํ† ํฐ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

Salt ์—†์ด ํ•ด์‹œ๋ฅผ ๊ณ„์‚ฐํ•  ๊ฒฝ์šฐ ์ถ”์ธก์„ ํ†ตํ•œ ๋Œ€์ž… ๊ณต๊ฒฉ์— ๋…ธ์ถœ๋˜๊ธฐ์— ์‹ค์ œ ๋ฐฐํฌ ์‹œ ๋ณด์•ˆ์„ ์œ„ํ•ด ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Salt๋กœ SHA-256 ํ•ด์‹œ๋ฅผ ๊ณ„์‚ฐํ•˜์—ฌ ์ผ๋ถ€๋ถ„์„ ํ† ํฐ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ๊ฒฝ๋กœ์—๋Š” ํ•ญ์ƒ ๊ฐ™์€ ํ† ํฐ์ด ๋‚˜์˜ค๊ธฐ์— Salt๋งŒ ๊ฐ™๋‹ค๋ฉด ์–ด๋–ค ํ™˜๊ฒฝ์—์„œ๋„ ๋™์ผํ•œ permalink๋ฅผ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Hooks

flowchart TB subgraph HOOKS["Hooks"] direction TB hook1["site:after_init"] hook2["documents:post_init"] hook3["documents:post_render"] end subgraph ACTION1["register_secret_collection"] a1_in["site"] a1_proc["Add secret collection\nRemove from exclude"] a1_out["site.config"] end subgraph ACTION2["apply_secret_permalink"] a2_in["doc"] a2_proc["Check secret doc\nGet token from UrlTokenizer\nSet permalink, sitemap"] a2_out["doc.data"] end subgraph ACTION3["inject_noindex"] a3_in["doc.output"] a3_proc["Check secret doc\nInsert noindex meta"] a3_out["doc.output"] end hook1 --> ACTION1 hook2 --> ACTION2 hook3 --> ACTION3 a1_in --> a1_proc --> a1_out a2_in --> a2_proc --> a2_out a3_in --> a3_proc --> a3_out

Hooks๋Š” ๋น„๋ฐ€ ์ปฌ๋ ‰์…˜์„ ์ƒ์„ฑํ•˜๊ณ  ๊ฒ€์ƒ‰ ์ œ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜์—ฌ ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ฉฐ, Jekyll ๋นŒ๋“œ์˜ Lifecycle์„ ๋”ฐ๋ผ ์„ธ ๋ฒˆ ๋ฐœ๋™๋ฉ๋‹ˆ๋‹ค.

site ์ดˆ๊ธฐํ™” ์ดํ›„ - ๋น„๋ฐ€ ์ปฌ๋ ‰์…˜์„ Jekyll collections์— ๋“ฑ๋ก

document ์ดˆ๊ธฐํ™” ์ดํ›„ - UrlTokenizer ํ˜ธ์ถœํ•˜์—ฌ ๋น„๋ฐ€ ์ปฌ๋ ‰์…˜์— ์†ํ•œ ๋ฌธ์„œ์˜ URL permalink ์ƒ์„ฑ, sitemap ์ œ์™ธ ์„ค์ •

๋ Œ๋”๋ง ์ดํ›„ - ๋น„๋ฐ€ ์ปฌ๋ ‰์…˜์˜ ๋ Œ๋”๋ง๋œ HTML์— robots ๋ฉ”ํƒ€ ํƒœ๊ทธ ์‚ฝ์ž…ํ•˜์—ฌ ๊ฒ€์ƒ‰ ์—”์ง„ ์ธ๋ฑ์‹ฑ ๋ฐฉ์ง€


Generator

flowchart LR subgraph INPUT["Input"] site["site"] end subgraph GEN["Generator"] a["add_secret_index_page"] l["log_secret_urls"] end subgraph OUT["Output"] page["Redirect page - index.html"] urls["URL list"] end site --> a site --> l a --> page l -->|"if list_urls"| urls

Generator๋Š” ๋น„๋ฐ€ ๋ฌธ์„œ URL์˜ ์ ‘๊ทผ ๋ฐฉ์‹์„ ๊ด€๋ฆฌํ•˜๋ฉฐ, Jekyll ๋นŒ๋“œ Lifecycle ์ค‘ ๋ Œ๋”๋ง ์ด์ „์— ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

Jekyll์€ ๋นŒ๋“œ ์‹œ ๋น„๋ฐ€ ๋ฌธ์„œ ๊ฒฝ๋กœ(_site/s/) ๋ฐ”๋กœ ์•„๋ž˜์— index.html์„ ์ž๋™ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , _site/s/<token>/index.html๊ณผ ๊ฐ™์€ ๊ฐœ๋ณ„ ๋ฌธ์„œ๋งŒ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋งŒ์•ฝ ์›น ์„œ๋ฒ„๊ฐ€ ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฆฌ์ŠคํŒ…(Apache - mod_autoindex, Nginx - autoindex)์„ ์ง€์›ํ•  ๊ฒฝ์šฐ, ๋น„๋ฐ€ ๊ฒฝ๋กœ /s/์— ์ ‘๊ทผ ์‹œ ๊ฐ€๋ ค์ ธ์•ผ ํ•  ํ•˜์œ„ ๋ฌธ์„œ๋“ค์˜ URL๋“ค์„ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด Generator๋Š” ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ์šฉ index.html ํŽ˜์ด์ง€๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋น„๋ฐ€ ๊ฒฝ๋กœ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋น„๋ฐ€ ๊ฒฝ๋กœ์— ์ ‘๊ทผํ•  ์‹œ ์„ค์ •์—์„œ ์ง€์ •ํ•œ ๊ฒฝ๋กœ(redirect_url)๋กœ ์ž๋™ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ๋˜๋„๋ก ํ•ด ๋””๋ ‰ํ„ฐ๋ฆฌ ๋ฆฌ์ŠคํŒ…์œผ๋กœ ์ธํ•œ URL ์œ ์ถœ์„ ์ฐจ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋”๋ถˆ์–ด, Generator๋Š” list_urls์ด ์ผœ์ ธ ์žˆ์„ ๊ฒฝ์šฐ ๋น„๋ฐ€ ์ปฌ๋ ‰์…˜์˜ URL์„ ๋นŒ๋“œ ๋กœ๊ทธ์— ์ถœ๋ ฅํ•˜๋Š” ์—ญํ• ์„ ๋งก์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์˜ ์„ค๊ณ„์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์€ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ๋ฌธ๋‹จ์—์„œ ํ›„์ˆ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


Jekyll Lifecycle

flowchart LR subgraph LIFECYCLE["Jekyll Lifecycle"] direction LR s1["Init"] s2["Read"] s3["Generate"] s4["Render"] s5["Write"] end s1 --> s2 --> s3 --> s4 --> s5 h1["after_init\nregister_secret"] h2["post_init\napply_permalink"] g["Generator"] h3["post_render\ninject_noindex"] s1 -.-> h1 s2 -.-> h2 s3 -.-> g s4 -.-> h3

ํ”Œ๋Ÿฌ๊ทธ์ธ์€ Jekyll ๋นŒ๋“œ Lifecycle์˜ Init, Read, Generate, Render ๋„ค ์‹œ์ ์„ ๋”ฐ๋ผ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

Init

Init ๋‹จ๊ณ„ ์งํ›„ site:after_init ํ›…์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ปฌ๋ ‰์…˜ ์„ค์ • ํ™•์ • ์ด์ „ ์‹œ์ ์— ๋น„๋ฐ€ ํฌ์ŠคํŠธ ์ปฌ๋ ‰์…˜์„ collections์— ๋“ฑ๋กํ•˜๊ณ , ์†Œ์Šค ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฐ€ exclude์— ํฌํ•จ๋ผ ์žˆ์œผ๋ฉด ์ œ๊ฑฐํ•˜์—ฌ Jekyll์ด _secret/ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ฝ๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.

Read

๋นŒ๋“œ ๊ณผ์ •์—์„œ ๋ฌธ์„œ ๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์งˆ ๋•Œ๋งˆ๋‹ค documents:post_init ํ›…์ด ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ๋น„๋ฐ€ ์ปฌ๋ ‰์…˜์— ์†ํ•œ ๋ฌธ์„œ์˜ URL์„ ํ•ด์‹œ๋œ permalink๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

Generate

Generator ๋‹จ๊ณ„์—์„œ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋‚ด๋ถ€์˜ Generator๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. URL prefix ๊ฒฝ๋กœ์— ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ์šฉ index.html์„ ์ถ”๊ฐ€ํ•˜๊ณ , ์„ค์ •์— ๋”ฐ๋ผ ๋น„๋ฐ€ ํฌ์ŠคํŠธ URL ๋ชฉ๋ก์„ ๋นŒ๋“œ ๋กœ๊ทธ์— ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

Render

๋ฌธ์„œ ๋ Œ๋”๋ง ์ดํ›„, ๊ฐ ๋ฌธ์„œ์˜ HTML์ด ์ƒ์„ฑ๋œ ์ƒํƒœ์—์„œ documents:post_render ํ›…์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋น„๋ฐ€ ์ปฌ๋ ‰์…˜ ๋ฌธ์„œ์˜ HTML ์ƒ๋‹จ์— noindex ๋ฉ”ํƒ€ ํƒœ๊ทธ๋ฅผ ์‚ฝ์ž…ํ•ด ๊ฒ€์ƒ‰ ์—”์ง„ ์ธ๋ฑ์‹ฑ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.


ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

1. ๋น„๋ฐ€ ํฌ์ŠคํŠธ URL ํ™•์ธ ๋ฐฉ๋ฒ•

๋น„๋ฐ€ URL์€ ํ•ด์‹œ๋กœ ๊ณ„์‚ฐ๋˜๊ธฐ์— ๊ฐ’์„ ์—์ธกํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ์‚ฌ์šฉ์ž๋Š” ๋นŒ๋“œ๋œ _site ํŒŒ์ผ์„ ์ง์ ‘ ๊นŒ๋ณด์ง€ ์•Š๋Š” ์ด์ƒ ๋น„๋ฐ€ URL์„ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, ๋นŒ๋“œ ์‹œ ์ถœ๋ ฅ๋˜๋Š” ๋กœ๊ทธ์—์„œ URL์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋งŒ์•ฝ CI/CD๋‚˜ ์™ธ๋ถ€ ์„œ๋ฒ„ ๋“ฑ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ํ™˜๊ฒฝ์—์„œ ๋™์ผํ•œ ๋กœ๊ทธ๊ฐ€ ์ถœ๋ ฅ๋  ๊ฒฝ์šฐ ๋น„๋ฐ€ URL์ด ์œ ์ถœ๋  ์ˆ˜ ์žˆ๊ธฐ์—, ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์ˆ˜๋™์œผ๋กœ ํ™œ์„ฑํ™”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ถœ๋ ฅํ•˜๋„๋ก ์ œํ•œ์„ ๋‘์–ด ์„ค๊ณ„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.


2. Jekyll ํ”Œ๋Ÿฌ๊ทธ์ธ ์ถฉ๋Œ

Jekyll ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์€ ๋นŒ๋“œ ๊ณผ์ •์—์„œ ์ปฌ๋ ‰์…˜, ๋ฌธ์„œ, permalink, ์ถœ๋ ฅ HTML ๊ฐ™์€ ๊ณตํ†ต ๊ฐ์ฒด๋“ค์„ ๋™์‹œ์— ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ๋‹ค๋ฅธ ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ ์ถฉ๋Œํ•˜์ง€ ์•Š๋„๋ก ๋™์‹œ์„ฑ์„ ๊ณ ๋ คํ•œ ์„ค๊ณ„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ด ํ”Œ๋Ÿฌ๊ทธ์ธ ๋˜ํ•œ ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ์ถฉ๋Œ ๋ฐฉ์ง€๋ฅผ ๊ณ ๋ฏผํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๊ฒฐํ•œ ์ถฉ๋Œ ์ผ€์ด์Šค๋“ค์„ ์†Œ๊ฐœํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ถฉ๋Œ ์œ ํ˜• ์›์ธ ํ•ด๊ฒฐ ๋ฐฉ์‹
๊ฒฝ๋กœ ์ถฉ๋Œ ๊ธฐ์กด ์ปฌ๋ ‰์…˜๊ณผ ์ด๋ฆ„/๊ฒฝ๋กœ ์ค‘๋ณต ๋ฎ์–ด์“ฐ์ง€ ์•Š๋„๋ก ์กฐ์น˜, ๋น„๋ฐ€ ์ปฌ๋ ‰์…˜ ์ด๋ฆ„/๊ฒฝ๋กœ ์„ค์ • ์ง€์›
permalink ์ค‘๋ณต ์ˆ˜์ • ์—ฌ๋Ÿฌ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ๊ฐ™์€ permalink๋ฅผ ์ˆ˜์ • ๋น„๋ฐ€ ์ปฌ๋ ‰์…˜์œผ๋กœ ๋™์ž‘ ๋ฒ”์œ„ ํ•œ์ •
sitemap ์ƒ์„ฑ jekyll-sitemap ํ”Œ๋Ÿฌ๊ทธ์ธ์ด Generator ๋‹จ๊ณ„์—์„œ sitemap ์ˆ˜์ง‘ Generator ์ด์ „ documents:post_init ํ›…์—์„œ ๋น„๋ฐ€ ๋ฌธ์„œ์— doc.data["sitemap"] = false ์„ค์ •


๊ฒฐ๊ณผ

GitHub Repository Preview Image Gem Version

๊ฐœ๋ฐœํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ GitHub์™€ RubyGems์— ๊ณต๊ฐœ ๋ฐฐํฌํ–ˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ GitHub Repository์—์„œ ์‚ฌ์šฉํ•ด ๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„์ด ์ฝ๊ณ  ๊ณ„์‹  ์ด ๋ธ”๋กœ๊ทธ์—๋„ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์ ์šฉ๋˜์–ด ๋ธ”๋กœ๊ทธ ์–ด๋”˜๊ฐ€, ์ €๋งŒ ์•„๋Š” URL์— ๊ฒฝ๋ ฅ ๊ฒฝํ—˜์„ ๋‹ด์€ ๊ธ€์ด ์—…๋กœ๋“œ๋˜์–ด ์ œ ์ด๋ ฅ์„œ๋ฅผ ์ฑ„์›Œ์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ–ฅํ›„์—๋„ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋ฉฐ ํ•„์š”์„ฑ์„ ๋А๋‚€ ๊ธฐ๋Šฅ๋“ค์„ ์ถ”๊ฐ€ํ•ด ๋‚˜๊ฐˆ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๊ธฐ์—ฌ๋Š” ์–ธ์ œ๋‚˜ ํ™˜์˜์ž…๋‹ˆ๋‹ค!